/*
    创建者：shuxiaokai
    创建时间：2022-09-04 21:37
    模块名称：本地包数据
    备注：
*/
<template>
  <div class="package-wrap">
    <s-resize-x :min="600" :max="600" :width="600" name="package" tabindex="1">
      <div class="package-upload">
        <el-form ref="form" :model="formInfo" :rules="rules" label-width="150px">
          <el-form-item label="包名(不允许重复)" prop="name">
            <el-input v-model="formInfo.name" placeholder="请输入包名称" maxlength="125" clearable show-word-limit></el-input>
          </el-form-item>
          <el-form-item label="上传js文件" prop="code">
            <el-upload
              class="w-100"
              drag
              action=""
              accept="text/javascript"
              :show-file-list="false"
              :before-upload="handleBeforeUpload"
              :http-request="requestHook"
            >
              <div class="el-upload__text">将文件拖到此处，或<em>点击上传</em></div>
            </el-upload>
          </el-form-item>
          <el-form-item label="源码展示">
            <pre class="code-wrap">{{ formInfo.code }}</pre>
          </el-form-item>
          <el-form-item>
            <el-button type="primary" @click="handleAddScript">确定添加</el-button>
          </el-form-item>
        </el-form>
      </div>
    </s-resize-x>
    <div class="flex1">
      <el-table :data="tableInfo" stripe border size="mini" height="450px">
        <el-table-column prop="name" label="包名" align="center"></el-table-column>
        <el-table-column label="源码" align="center">
          <template #default="scope">
            <el-button type="primary" text @click="handleOpenCodeDialog(scope.row)">源码</el-button>
            <el-button type="primary" text @click="handleDeletepackage(scope.row)">删除</el-button>
          </template>
        </el-table-column>
      </el-table>
    </div>
    <s-dialog v-model="codeVisible" :title="title">
      <pre class="code-wrap">{{ code }}</pre>
    </s-dialog>
  </div>
</template>

<script lang="ts" setup>
import { ElMessage, ElMessageBox } from 'element-plus';
import { onMounted, Ref, ref } from 'vue';
import { FormInstance } from 'element-plus/lib/components/form';
import { UploadRequestHandler, UploadRequestOptions } from 'element-plus/lib/components/upload/src/upload';
import db from '@/cache/database';

//获取脚本列表
const tableInfo: Ref<{ name: string, code: string }[]> = ref([]);
const getScriptList = () => {
  db.scriptList.toArray().then(res => {
    tableInfo.value = res;
  })
}
/*
|--------------------------------------------------------------------------
| 表单填写
|--------------------------------------------------------------------------
*/
const form: Ref<FormInstance | null> = ref(null);
const formInfo = ref({
  code: '',
  name: '',
});
const rules = ref({
  name: [{ required: true, message: '请输入包名', trigger: 'blur' }],
  code: [{ required: true, message: '请上传js文件', trigger: 'change' }],
});
//检查文件格式和文件大小
const handleBeforeUpload = (file: File) => {
  const standerFileType = file.type; //标准类型
  const matchSuffix = file.name.match(/(?<=\.)[^.]+$/); //根据后缀获取类型
  const suffixFileType = matchSuffix ? matchSuffix[0] : '';
  if (!standerFileType && !suffixFileType) {
    ElMessage.error('未知的文件格式，无法解析');
    return false;
  }
  if (standerFileType !== 'text/javascript') {
    ElMessage.error('仅支持js文件上传');
    return false;
  }
  if (file.size > 1024 * 1024 * 20) {
    ElMessage.error('文件大小不超过20M');
    return false;
  }
  return true;
}
//发送请求钩子
const requestHook: UploadRequestHandler = (options: UploadRequestOptions) => {
  const { file } = options;
  return new Promise((resolve, reject) => {
    file.text().then((stringScript) => {
      formInfo.value.code = stringScript
      resolve(stringScript)
    }).catch(err => {
      reject(err)
    })
  })
}
//新增脚本
const handleAddScript = () => {
  if (form.value) {
    form.value.validate(async (valid) => {
      if (valid) {
        const scriptList = await db.scriptList.toArray();
        if (scriptList.find(v => v.name === formInfo.value.name)) {
          ElMessage.warning('当前安装包名称已存在')
        } else {
          db.scriptList.add({
            name: formInfo.value.name,
            code: formInfo.value.code
          })
          getScriptList();
        }
      }
    })
  }
}
/*
|--------------------------------------------------------------------------
| table操作相关
|--------------------------------------------------------------------------
*/
const codeVisible = ref(false);
const code = ref('');
const title = ref('');
//打开安装包弹窗
const handleOpenCodeDialog = (info: { name: string, code: string }) => {
  codeVisible.value = true;
  code.value = info.code;
  title.value = info.name;
}
//删除包
const handleDeletepackage = async (info: { name: string, code: string }) => {
  ElMessageBox.confirm('此操作将永久删除此条记录, 是否继续?', '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning'
  }).then(async () => {
    await db.scriptList.where('name').anyOf(info.name).delete();
    getScriptList();
  }).catch((err) => {
    console.error(err);
  });
}
//读取脚本信息
onMounted(() => {
  getScriptList();
})
</script>

<style lang="scss" scoped>
.package-wrap {
    display: flex;
    height: calc(100vh - #{size(100)});
    overflow-y: auto;
    .drag-wrap {
        border-right: 1px solid $gray-500;
    }
    .package-upload {
        padding: size(20);
        height: 100%;
    }
}
.code-wrap {
    width: 100%;
    min-height: size(200);
    max-height: size(400);
    overflow-y: auto;
}
</style>
